package practica1compi1;


import java.io.*;
import goldengine.java.*;
import javax.swing.JOptionPane;

/*
 * Licensed Material - Property of Matthew Hawkins (hawkini@4email.net) 
 */
 
public class Practica1Gramatica implements GPMessageConstants
{
 
    private interface SymbolConstants 
    {
       final int SYMBOL_EOF           =  0;  // (EOF)
       final int SYMBOL_ERROR         =  1;  // (Error)
       final int SYMBOL_WHITESPACE    =  2;  // (Whitespace)
       final int SYMBOL_LPARAN        =  3;  // '('
       final int SYMBOL_RPARAN        =  4;  // ')'
       final int SYMBOL_TIMES         =  5;  // '*'
       final int SYMBOL_DOT           =  6;  // '.'
       final int SYMBOL_QUESTION      =  7;  // '?'
       final int SYMBOL_PIPE          =  8;  // '|'
       final int SYMBOL_PLUS          =  9;  // '+'
       final int SYMBOL_ID            = 10;  // ID
       final int SYMBOL_CUERPO        = 11;  // <cuerpo>
       final int SYMBOL_IDENTIFICADOR = 12;  // <identificador>
       final int SYMBOL_INICIO        = 13;  // <inicio>
       final int SYMBOL_PARENTESIS    = 14;  // <parentesis>
       final int SYMBOL_PARTE1        = 15;  // <parte1>
       final int SYMBOL_SIMBOLO       = 16;  // <simbolo>
    };

    private interface RuleConstants
    {
       final int RULE_INICIO                   =  0;  // <inicio> ::= <cuerpo>
       final int RULE_CUERPO_PIPE              =  1;  // <cuerpo> ::= <parte1> '|' <cuerpo>
       final int RULE_CUERPO_DOT               =  2;  // <cuerpo> ::= <parte1> '.' <cuerpo>
       final int RULE_CUERPO                   =  3;  // <cuerpo> ::= <parte1>
       final int RULE_PARTE1                   =  4;  // <parte1> ::= <parentesis>
       final int RULE_PARTE12                  =  5;  // <parte1> ::= <parentesis> <simbolo>
       final int RULE_PARTE13                  =  6;  // <parte1> ::= <identificador> <simbolo>
       final int RULE_PARTE14                  =  7;  // <parte1> ::= <identificador>
       final int RULE_PARENTESIS_LPARAN_RPARAN =  8;  // <parentesis> ::= '(' <cuerpo> ')'
       final int RULE_SIMBOLO_TIMES            =  9;  // <simbolo> ::= '*'
       final int RULE_SIMBOLO_PLUS             = 10;  // <simbolo> ::= '+'
       final int RULE_SIMBOLO_QUESTION         = 11;  // <simbolo> ::= '?'
       final int RULE_IDENTIFICADOR_ID         = 12;  // <identificador> ::= ID
    };

   private static BufferedReader buffR;
   public String polaca;
   public boolean Result=false;
   int contador=0;
    /***************************************************************
     * This class will run the engine, and needs a file called config.dat
     * in the current directory. This file should contain two lines,
     * The first should be the absolute path name to the .cgt file, the second
     * should be the source file you wish to parse.
     * @param args Array of arguments.
     ***************************************************************/
    public void parser()
    {
       String textToParse = "", compiledGrammar = "";
       Result=false;
       try
       {
           buffR = new BufferedReader(new FileReader(new File("C:\\Users\\Public\\Documents\\config.dat")));
           compiledGrammar = buffR.readLine();
           textToParse = buffR.readLine();
           buffR.close();
       }
       
       catch(FileNotFoundException fnfex)
       {
           System.out.println("Config File was not found.\n\n" +
                              "Please place it in the current directory.");
           System.exit(1);
       }
       catch(IOException ioex)
       {
          System.out.println("An error occured while reading config.dat.\n\n" +
                             "Please re-try ensuring the file can be read.");
          System.exit(1);
       }
       
       GOLDParser1 parser = new GOLDParser1();
       parser.setTrimReductions(false);

       try
       {
          parser.loadCompiledGrammar(compiledGrammar);
          parser.openFile(textToParse);
       }
       catch(ParserException parse)
       {
          System.out.println("**PARSER ERROR**\n" + parse.toString());
          System.exit(1);
       }

       boolean done = false;
       int response = -1;
       int i = 1;
       
       //Try para Escribir errores en html
       try{
            FileWriter fw = new FileWriter("C:\\Users\\Public\\Documents\\erores.html",false);
            PrintWriter pw =new PrintWriter(fw);
            
            pw.println("<html>");
            pw.println("<head>");
            pw.println("<link href=\"default.css\" rel=\"stylesheet\" type=\"text/css\" />");
            pw.println("</head>");
            pw.println("<br><br>");
            pw.println("<h1><center>");
            pw.println("Errores Lexicos Y Sintacticos");
            pw.println("</center></h1>");
            pw.println("<body>");
            pw.println("<table align=\"center\">");
            
                
       while(!done)
       {
          try
            {
                  response = parser.parse();
            }
            catch(ParserException parse)
            {
                System.out.println("**PARSER ERROR**\n" + parse.toString());
                System.exit(1);
            }

            switch(response)
            {
               case gpMsgTokenRead:
                   /* A token was read by the parser. The Token Object can be accessed
                      through the CurrentToken() property:  Parser.CurrentToken */
                   break;

               case gpMsgReduction:
                   /* This message is returned when a rule was reduced by the parse engine.
                      The CurrentReduction property is assigned a Reduction object
                      containing the rule and its related tokens. You can reassign this
                      property to your own customized class. If this is not the case,
                      this message can be ignored and the Reduction object will be used
                      to store the parse tree.  */

                      switch(parser.currentReduction().getParentRule().getTableIndex())
                      {
                         case RuleConstants.RULE_INICIO:
                            //<inicio> ::= <cuerpo>
                              Reduction r2811 = (Reduction) parser.currentReduction().getToken(0).getData();
                              polaca = r2811.getToken(0).getData().toString();
                            break;
                         case RuleConstants.RULE_CUERPO_PIPE:
                            //<cuerpo> ::= <parte1> '|' <cuerpo>
                             Reduction r281 = (Reduction) parser.currentReduction().getToken(0).getData();
                             Reduction r291 = (Reduction) parser.currentReduction().getToken(2).getData();
                            parser.currentReduction().getToken(0).setData("|("+r281.getToken(0).getData().toString()+")("+r291.getToken(0).getData().toString()+")");
                             break;
                         case RuleConstants.RULE_CUERPO_DOT:
                            //<cuerpo> ::= <parte1> '.' <cuerpo>
                            Reduction r28 = (Reduction) parser.currentReduction().getToken(0).getData();
                             Reduction r29 = (Reduction) parser.currentReduction().getToken(2).getData();
                            parser.currentReduction().getToken(0).setData(".("+r28.getToken(0).getData().toString()+")("+r29.getToken(0).getData().toString()+")");
                            break;
                         case RuleConstants.RULE_CUERPO:
                            //<cuerpo> ::= <parte1>
                             Reduction r27 = (Reduction) parser.currentReduction().getToken(0).getData();
                             parser.currentReduction().getToken(0).setData(r27.getToken(0).getData().toString());
                            break;
                         case RuleConstants.RULE_PARTE1:
                            //<parte1> ::= <parentesis>
                             Reduction r26 = (Reduction) parser.currentReduction().getToken(0).getData();
                             parser.currentReduction().getToken(0).setData(r26.getToken(0).getData().toString());
                            break;
                         case RuleConstants.RULE_PARTE12:
                            //<parte1> ::= <parentesis> <simbolo>
                             Reduction r24 = (Reduction) parser.currentReduction().getToken(0).getData();
                            Reduction r25 = (Reduction) parser.currentReduction().getToken(1).getData();
                            
                             parser.currentReduction().getToken(0).setData(r25.getToken(0).getData().toString()+"("+r24.getToken(0).getData().toString()+")");
                            break;
                         case RuleConstants.RULE_PARTE13:
                            //<parte1> ::= <identificador> <simbolo>
                             Reduction r22 = (Reduction) parser.currentReduction().getToken(0).getData();
                            Reduction r23 = (Reduction) parser.currentReduction().getToken(1).getData();
                            
                             parser.currentReduction().getToken(0).setData(r23.getToken(0).getData().toString()+"("+r22.getToken(0).getData().toString()+")");
//                            Reduction r1 = (Reduction) parser.currentReduction().getToken(0).getData();
//                            Reduction r3 = (Reduction) parser.currentReduction().getToken(1).getData();
//                            if(r3.getToken(0).getData().equals("*")){
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \""+r1.getToken(0).getData()+"\" ] ");
//                                System.out.println("s"+i+" -> s"+(i-1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+(i-3)+" -> s"+(i)+" [ label = \"&epsilon;\" ]");
//                                
//                            }else if (r3.getToken(0).getData().equals("+")){
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \""+r1.getToken(0).getData()+"\" ] ");
//                                System.out.println("s"+i+" -> s"+(i-1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                            }else if (r3.getToken(0).getData().equals("?")){
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \""+r1.getToken(0).getData()+"\" ] ");
//                                System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                                System.out.println("s"+(i-3)+" -> s"+(i)+" [ label = \"&epsilon;\" ]");
//                            }else {
//                                
//                            }
                            break;
                             
                         case RuleConstants.RULE_PARTE14:
                            //<parte1> ::= <identificador>
                            Reduction r2 = (Reduction) parser.currentReduction().getToken(0).getData();
                            parser.currentReduction().getToken(0).setData(r2.getToken(0).getData().toString());
                            //System.out.println("id = "+r2.getToken(0).getData().toString());
//                            System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
//                            System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \""+r2.getToken(0).getData()+"\" ] ");
//                            System.out.println("s"+i+" -> s"+(i=i+1)+" [ label = \"&epsilon;\" ]");
                            break;
                             
                         case RuleConstants.RULE_PARENTESIS_LPARAN_RPARAN:
                            //<parentesis> ::= '(' <cuerpo> ')'
                             Reduction r21 = (Reduction) parser.currentReduction().getToken(1).getData();
                            parser.currentReduction().getToken(0).setData(r21.getToken(0).getData().toString());
                            break;
                             
                         case RuleConstants.RULE_SIMBOLO_TIMES:
                            //<simbolo> ::= '*'
                            String por = parser.currentReduction().getToken(0).getData().toString();
                            parser.currentReduction().getToken(0).setData(por.toString());
                            break;
                         case RuleConstants.RULE_SIMBOLO_PLUS:
                            //<simbolo> ::= '+'
                            String mas = parser.currentReduction().getToken(0).getData().toString();
                            parser.currentReduction().getToken(0).setData(mas.toString());
                            break;
                             
                         case RuleConstants.RULE_SIMBOLO_QUESTION:
                            //<simbolo> ::= '?'
                            String sig = parser.currentReduction().getToken(0).getData().toString();
                            parser.currentReduction().getToken(0).setData(sig.toString());
                            break;
                             
                         case RuleConstants.RULE_IDENTIFICADOR_ID:
                            //<identificador> ::= ID
                            String id = parser.currentReduction().getToken(0).getData().toString();
                            parser.currentReduction().getToken(0).setData(id.toString());
                            break;
                             
                      }

                          //Parser.Reduction = //Object you created to store the rule

                    // ************************************** log file
                    //System.out.println("gpMsgReduction");
                    Reduction myRed = parser.currentReduction();
                   // System.out.println(myRed.getParentRule().getText());
                    // ************************************** end log

                    break;

                case gpMsgAccept:
                    /* The program was accepted by the parsing engine */

                    // ************************************** log file
                    System.out.println("-- Accept --");
                    System.out.println(polaca);
                    Result=true;
                    // ************************************** end log

                    done = true;
                    break;

                case gpMsgLexicalError:
                    /* Place code here to handle a illegal or unrecognized token
                           To recover, pop the token from the stack: Parser.PopInputToken */

                    // ************************************** log file
                    System.out.println("gpMsgLexicalError");
                    // ************************************** end log

                    System.out.println(   "ERROR LEXICO!!!  Lexema: "   +    parser.currentToken().getData().toString()  +"  Linea: " + parser.currentLineNumber());
                    
                    pw.println("<tr>");
                    pw.println("<td>");
                    pw.println("ERROR LEXICO!!!  Lexema: "   +    parser.currentToken().getData().toString()  +"  Linea: " + parser.currentLineNumber());
                    pw.println("</td>");
                    pw.println("</tr>");
                    contador++;
                    parser.popInputToken();
                    
                    break;

                case gpMsgNotLoadedError:
                    /* Load the Compiled Grammar Table file first. */

                    // ************************************** log file
                    System.out.println("gpMsgNotLoadedError");
                    // ************************************** end log

                    done = true;
                    break;

                case gpMsgSyntaxError:
                    /* This is a syntax error: the source has produced a token that was
                           not expected by the LALR State Machine. The expected tokens are stored
                           into the Tokens() list. To recover, push one of the
                              expected tokens onto the parser's input queue (the first in this case):
                           You should limit the number of times this type of recovery can take
                           place. */

                         //<editor-fold defaultstate="collapsed" desc="aqui intentamos sacar el primer caracter del lexema si no se puede se saca el token">
                    try {
                        //<editor-fold defaultstate="collapsed" desc="sacamos el primer caracter del lexema">
                        char caracter = parser.currentToken().getData().toString().charAt(0);
                        //</editor-fold>
                        //<editor-fold defaultstate="collapsed" desc="imprimimosel lexema y el numero de linea">
                         System.out.println(   "ERROR SINTACTICO!!!  Lexema: "   +    parser.currentToken().getData().toString()  +"  Linea: " + parser.currentLineNumber());
                         
                         
                         pw.println("<tr>");
                         pw.println("<td>");
                         pw.println("ERROR SINTACTICO!!!  Lexema: "   +    parser.currentToken().getData().toString()  +"  Linea: " + parser.currentLineNumber());
                         pw.println("</td>");
                         pw.println("</tr>");
                         contador++;
                         
                        //</editor-fold>
                         //<editor-fold defaultstate="collapsed" desc="mandamos el token a la verga">
                         parser.popInputToken();
                         //</editor-fold>
                    } catch (Exception e) {
                        //<editor-fold defaultstate="collapsed" desc="si el token no trae un lexema entonces termina el analisis">
                         done=true;
                         //</editor-fold>
                    }
                    
                                            //</editor-fold>

                    
                    
                        
                    break;

                case gpMsgCommentError:
                    /* The end of the input was reached while reading a comment.
                             This is caused by a comment that was not terminated */

                    // ************************************** log file
                    System.out.println("gpMsgCommentError");
                    // ************************************** end log

                    done = true;

                              break;

                case gpMsgInternalError:
                    /* Something horrid happened inside the parser. You cannot recover */

                    // ************************************** log file
                    System.out.println("gpMsgInternalError");
                    // ************************************** end log

                    done = true;

                    break;
            }
        }
        try
        {
              parser.closeFile();
        }
        catch(ParserException parse)
        {
            System.out.println("**PARSER ERROR**\n" + parse.toString());
            System.exit(1);
        }
     
        //Cierre de Archivo html Incluye el catch del writer...
        
                pw.println("</table>");
                pw.println("</body>");
                pw.println("</html>");
                pw.close();
            
                if(contador>0){
                JOptionPane.showMessageDialog(null, "Se encontraron Errores en la ER Verificar...");
                }
                
        } catch(Exception e){
            
        }
    
    }
}
